package com.wstuo.common.tools.service;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import com.wstuo.common.config.dictionary.dao.IDataDictionaryItemsDAO;
import com.wstuo.common.noticeRule.dto.NoticeInfoDTO;
import com.wstuo.common.noticeRule.service.INoticeRuleService;
import com.wstuo.common.tools.dao.ITaskDAO;
import com.wstuo.common.tools.dto.CostDTO;
import com.wstuo.common.tools.dto.HistoryRecordDTO;
import com.wstuo.common.tools.dto.ScheduleJsonDTO;
import com.wstuo.common.tools.dto.TaskDTO;
import com.wstuo.common.tools.dto.TaskQueryDTO;
import com.wstuo.common.tools.dto.TaskShowDataDTO;
import com.wstuo.common.tools.dto.TaskViewDTO;
import com.wstuo.common.tools.entity.Task;
import com.wstuo.common.tools.entity.TaskCycle;
import com.wstuo.common.tools.util.TaskCycleUtil;
import com.wstuo.common.tools.util.ToolsConstant;
import com.wstuo.common.dto.PageDTO;
import com.wstuo.common.file.csv.CSVWriter;
import com.wstuo.common.security.dao.IUserDAO;
import com.wstuo.common.security.entity.User;
import com.wstuo.common.security.utils.AppContext;
import com.wstuo.common.security.utils.LanguageContent;
import com.wstuo.common.util.StringUtils;
import com.wstuo.common.util.TimeUtils;

/**
 * 任务Service class
 * 
 * @author WSTUO
 * 
 */
public class TaskService implements ITaskService {
	private final static Logger LOGGER = Logger.getLogger(TaskService.class);
	@Autowired
	private ITaskDAO taskDao;
	@Autowired
	private INoticeRuleService noticeRuleService;
	@Autowired
	private IUserDAO userDAO;
	@Autowired
	private IHistoryRecordService historyRecordService;
	@Autowired
	private AppContext appctx;
	@Autowired
	private IDataDictionaryItemsDAO dataDictionaryItemsDAO;
	@Autowired
	private ICostService costService;
	private final static String EXPORTTASK_ERROR_INFO1 = "exportTask_StringWriter_UnsupportedEncod";

	/**
	 * 任务分页查询
	 * 
	 * @param taskQueryDto
	 * @param start
	 * @param limit
	 * @return PageDTO
	 */
	@SuppressWarnings("unchecked")
	@Transactional
	public PageDTO findPagerTask(TaskQueryDTO taskQueryDto, int start, int limit,
			String sidx, String sord) {
		if ( taskQueryDto != null && 
				(taskQueryDto.getStartTime() == null || taskQueryDto.getEndTime() == null) ) {
			taskQueryDto.setStartTime( TimeUtils.getMonthFirstDay( null ));
			taskQueryDto.setEndTime( TimeUtils.getMonthLastDay( null ));
		}
		PageDTO p = taskDao.findPagerTaskDAO(taskQueryDto, start, limit, sidx, sord);
		List<Task> entities = (List<Task>) p.getData();
		List<TaskDTO> dtos = new ArrayList<TaskDTO>(entities.size());
		for (Task entity : entities) {
			TaskDTO adto = new TaskDTO();
			entity2dto(entity, adto);
			dtos.add(adto);
		}
		p.setData(dtos);
		return p;
	}

	/**
	 * 查找最近任务，默认显示本月任务
	 * @param taskQueryDto 提供查询的参数
	 * @return
	 */
	public List<TaskDTO> findMyTaskForRecently(TaskQueryDTO taskQueryDto) {
		if ( taskQueryDto != null && 
				(taskQueryDto.getStartTime() == null || taskQueryDto.getEndTime() == null) ) {
			taskQueryDto.setStartTime( TimeUtils.getMonthFirstDay( null ));
			taskQueryDto.setEndTime( TimeUtils.getMonthLastDay( null ));
		}
		List<Task> entities = taskDao.findMyAllTask(taskQueryDto);
		if (taskQueryDto.isCycle() ) {
			entities = TaskCycleUtil.taskCycleResolve(entities, taskQueryDto);
		}
		List<TaskDTO> dtos = new ArrayList<TaskDTO>(entities.size());
		for (Task entity : entities) {
			TaskDTO adto = new TaskDTO();
			entity2dto(entity, adto);
			if ( adto.getTaskStatus().longValue() != -1L) {
				dtos.add(adto);
			}
		}
		return dtos;
	}

	/**
	 * 任务历史记录保存方法
	 * 
	 * @param taskDto
	 * @param logDetails
	 */
	@Transactional
	private void saveHistoryRecord(TaskDTO taskDto, String logDetails) {
		HistoryRecordDTO hrDto = new HistoryRecordDTO();
		hrDto.setEno(taskDto.getTaskId());
		hrDto.setLogDetails(logDetails);
		hrDto.setEventType( ToolsConstant.TYPE_OTHER_IS_TASK );
		hrDto.setCreatedTime(new Date());
		hrDto.setOperator(taskDto.getOperator());
		if (taskDto.getOperator() == null) {
			hrDto.setOperator( appctx.getCurrentLoginName() );
		}
		historyRecordService.saveHistoryRecord( hrDto );
	}

	/**
	 * 编辑任务
	 * 
	 * @param taskDto
	 */
	@Transactional
	public Long[] editTask(TaskDTO taskDto) {
		Long[] ids = new Long[1];

		Task task = taskDao.findById(taskDto.getTaskId());
		taskDto.setOwner(taskDto.getOwner());
		dto2entity(taskDto, task);
		taskDao.merge(task);
		ids[0] = taskDto.getTaskId();

		saveHistoryRecord(taskDto, "Edit Task");

		return ids;

	}

	/**
	 * 
	 */
	private void dto2entity(TaskDTO taskDto, Task task) {
		task.setAllDay(taskDto.getAllDay());//全天任务
		if (task.getAllDay() != null && task.getAllDay()) {
			taskDto.setStartTime( TimeUtils.getAllDayFirst( taskDto.getStartTime() ));
			taskDto.setEndTime( TimeUtils.getAllDayLast( taskDto.getEndTime() ));
		}
		//如果是周循环任务
		if ( ToolsConstant.TASK_TYPE_CYCLE_WEEK.equals( taskDto.getTaskCycle() ) ) {
			TaskCycle taskCycle = task.getTaskCycle();
			dto2entityWeek(taskDto, taskCycle);
			task.setTaskCycle(taskCycle);
		}
		
		task.setEndTime(taskDto.getEndTime());
		task.setStartTime(taskDto.getStartTime());
		task.setIntroduction(taskDto.getIntroduction());
		task.setTitle(taskDto.getTitle());
		task.setLocation(taskDto.getLocation());
		if (userDAO.findUserByLoginName(taskDto.getOwner()) != null) {
			task.setOwner(userDAO.findUserByLoginName(taskDto.getOwner()));
		}
		task.setTaskStatus(taskDto.getTaskStatus());
		task.setCreator(taskDto.getCreator());
		if (userDAO.findUserByLoginName(taskDto.getCreator()) != null) {
			task.setTaskCreator(userDAO.findUserByLoginName(taskDto.getCreator()));
		}
		if(taskDto.getTaskType()!=null){
			task.setType(dataDictionaryItemsDAO.findById(taskDto.getTaskType()));
		}
		if(StringUtils.hasText(taskDto.getDno())){
			task.setType(dataDictionaryItemsDAO.findUniqueBy("dno",taskDto.getDno()));
		}
		task.setRealStartTime(taskDto.getRealStartTime());
		task.setRealEndTime(taskDto.getRealEndTime());
		task.setRealFree(taskDto.getRealFree());
		task.setTreatmentResults(taskDto.getTreatmentResults());

	}
	
	private void dto2entityWeek(TaskDTO taskDto, TaskCycle taskCycle){
		taskCycle.setCycleCount( taskDto.getCycleCount() );
		taskCycle.setCycleType( taskDto.getCycleWeekEnd() );
		taskCycle.setType( taskDto.getTaskCycle() );
		if (taskDto.getWeekWeeks()!= null && taskDto.getWeekWeeks().length > 0) {
			StringBuffer buffer = new StringBuffer();
			for (String week : taskDto.getWeekWeeks()) {
				int w = ToolsConstant.weekIndex(week);
				if (w != 0) {
					buffer.append( w + ToolsConstant.TASK_TIME_SEPARATED);
				}
			}
			taskCycle.setDateStr(buffer.toString());
		}else{
			taskCycle.setDateStr(ToolsConstant.TASK_TIME_SEPARATED);
		}
		
		//循环时间
		Date cycleStart = taskDto.getStartTime();
		Date cycleEnd = taskDto.getEndTime();
		
		if (taskDto.getCycleWeekEnd() == null
				|| taskDto.getCycleWeekEnd().equals(ToolsConstant.TASK_TYPE_CYCLE_END_NO)) {
			taskDto.setEndDate( TimeUtils.getMaxDate() );
		//}else if (ToolsConstant.TASK_TYPE_CYCLE_END_DATE.equals(taskDto.getCycleWeekEnd())) {
			//taskDto.setEndTime( TimeUtils.dateTransform(taskDto.getEndDate(), cycleEnd) );
		}else if ( ToolsConstant.TASK_TYPE_CYCLE_END_COUNT.equals(taskDto.getCycleWeekEnd()) ) {
			int[] weeksIndex = taskCycle.getDateIndexVerify();
			if (weeksIndex != null && weeksIndex.length > 0) {
				taskDto.setEndDate( TimeUtils.calcDateWeekCount(taskDto.getStartDate(), 
						taskCycle.getCycleCount(),weeksIndex) );
			}
		}

		taskDto.setStartTime( TimeUtils.dateTransform(taskDto.getStartDate(), cycleStart) );
		taskDto.setEndTime( TimeUtils.dateTransform(taskDto.getEndDate(), cycleEnd) );
		taskDto.setStartDate( cycleStart );
		taskDto.setEndDate( cycleEnd );
		
		taskCycle.setStartDate( taskDto.getStartDate() );
		taskCycle.setEndDate( taskDto.getEndDate() );
	}

	/**
	 * 保存任务
	 * 
	 * @param taskDto
	 */
	@Transactional
	public Long[] saveTask(TaskDTO taskDto) {
		String[] owners = taskDto.getOwner().split(";");
		Long[] ids = new Long[owners.length];
		for (int i = 0; i < owners.length; i++) {
			if (StringUtils.hasText(owners[i])) {
				Task task = new Task();
				taskDto.setOwner(owners[i]);
				dto2entity(taskDto, task);
				taskDao.save(task);
				
				taskDto.setTaskId(task.getTaskId());
				ids[i] = task.getTaskId();
				taskNotice("taskNoticeOwner", task, taskDto.getOwner(),
						taskDto.getCreator(), taskDto.getOperator());
				// 保存历史记录
				saveHistoryRecord(taskDto, "Add Task");
			}
		}
		return ids;
	}

	/**
	 * 删除任务
	 * 
	 * @param taskIds
	 */
	@Transactional
	public void deleteTask(Long[] taskIds) {
		try {
			if(taskIds != null && taskIds.length > 0){
				List<Long> taskIds1 = Arrays.asList(taskIds);
				costService.deleteCostBySchedule(taskIds1);
				historyRecordService.deleteHistoryRecordByEno(taskIds,ToolsConstant.TYPE_OTHER_IS_TASK);
				taskDao.deleteByIds(taskIds);
				/*List<Long> taskIds1 = taskDao.findDeleteTask(taskIds);
				boolean flag = true;
				if ( taskIds1 != null && taskIds1.size() > 0) {
					costService.deleteCostBySchedule(taskIds1);
					historyRecordService.deleteHistoryRecordByEno(taskIds1,ToolsConstant.TYPE_OTHER_IS_TASK);
					taskDao.deleteByIds(taskIds1);
					flag =  taskIds1.size() < taskIds.length;
				}
				if (flag) {
					List<Long> taskIds2 = taskDao.findDeleteTaskCycle(taskIds);
					Long[] arrayIds = taskIds2.toArray(new Long[taskIds2.size()]);
					taskDao.endTask( arrayIds );
				}*/
			}
		} catch (Exception e) {
			LOGGER.error("TASKSERVICE_DELETETASK_ERROR",e);
		}
	}
	/**
	 * 删除任务（更改任务的进展及成本）
	 */
	@Transactional
	public void deleteScheduleTask(TaskDTO taskDto){
		TaskDTO dto = findTaskCost( taskDto );
		String taskCycle = dto.getTaskCycle();
		if (taskCycle == null 
				|| taskCycle.equals(ToolsConstant.TASK_TYPE_NORMAL)) {
			deleteTask(new Long[]{taskDto.getTaskId()});
		}else if ( ToolsConstant.TASK_TYPE_CYCLE_WEEK.equals( taskCycle )) {
			if ( TaskDTO.validTask(dto) && dto.getCostDTO() != null && dto.getCostDTO().checkProgressId() ) {
				CostDTO costDTO = dto.getCostDTO();
				costDTO.setStatus( -1L );
				costService.editCost(costDTO);
			}else{
				dto.setTaskStatus( -1L );
				saveTaskCost(dto);
			}
		}
	}
	
	/**
	 * 查询我的全部任务
	 * 
	 * @param taskQueryDto
	 * @return List<Task>
	 */
	@Transactional
	public List<Task> findAllTask(TaskQueryDTO taskQueryDto) {
		List<Task> taskList = taskDao.findMyAllTask(taskQueryDto);
		return taskList;
	}

	/**
	 * 判断同一时间段任务是否冲突
	 * 
	 * @param taskDTO
	 * @return boolean
	 */
	@Transactional
	public boolean timeConflict(TaskDTO taskDTO) {
		boolean blo = false;
		String[] owners = taskDTO.getOwner().split(";");
		for (int i = 0; i < owners.length; i++) {
			taskDTO.setOwner(owners[i]);
			if (taskDao.findSameTimeTask(taskDTO)) {
				blo = true;
			}
		}
		return blo;
	}

	/**
	 * 查询全部任务
	 * 
	 * @param taskQueryDto
	 * @return List<Task>
	 */
	@Transactional
	public List<ScheduleJsonDTO> findAllTaskShowSchedue(TaskQueryDTO taskQueryDto) {
		List<ScheduleJsonDTO> list = new ArrayList<ScheduleJsonDTO>();
		List<Task> taskList = taskDao.findMyAllTask(taskQueryDto);
		if (taskList != null) {
			taskList = TaskCycleUtil.taskCycleResolve(taskList, taskQueryDto);
			for (Task task : taskList) {
				ScheduleJsonDTO dto = new ScheduleJsonDTO();
				entity2dto(task, dto);
				if (dto.getTaskStatus().longValue() != -1L) {
					list.add(dto);
				}
			}
		}
		return list;
	}

	private void entity2dto(Task task, TaskDTO dto) {
		TaskDTO.entity2dto(task, dto);
		if (task == null) {
			return;
		}
		if(task.getCreateTime() !=null){
			dto.setCreatedOn(task.getCreateTime());
		}else{
			dto.setCreatedOn(new Date());
		}
		cycleTask2dto(task , dto);
		if (task.getOwner() != null) {
			dto.setOwner(task.getOwner().getFullName());
			dto.setOwnerLoginName(task.getOwner().getLoginName());
		}
		if(task.getType()!=null){
			dto.setDno(task.getType().getDno());
			dto.setType((task.getType().getDname()));
			dto.setdCode(task.getType().getDcode());
		}
		dto.setIntroduction(task.getIntroduction());
		dto.setLocation(task.getLocation());
		dto.setTaskStatus(task.getTaskStatus());
		if (task.getTaskCreator() != null) {
			dto.setCreator(task.getTaskCreator().getFullName());
			dto.setTaskCreator(task.getTaskCreator().getLoginName());
		}
		dto.setRealStartTime(task.getRealStartTime());
		dto.setRealEndTime(task.getRealEndTime());
		dto.setRealFree(task.getRealFree());
		dto.setTreatmentResults(task.getTreatmentResults());
		//通知模板需要的变量
		dto.setEtitle(task.getTitle());
		dto.setEdesc(task.getIntroduction());
		dto.setCreatedByName(task.getCreator());
		if(task.getStartTime()!=null && task.getEndTime()!=null)
		dto.setPlanTime(TimeUtils.format(task.getStartTime(), TimeUtils.DATE_PATTERN)+"——>"
		+TimeUtils.format(task.getEndTime(),TimeUtils.DATE_PATTERN));
		
		dto.setCostDTO( findTaskCostWith( task.getTaskId() , task.getStartTime() ,
				task.getEndTime(), task.taskCycleValue() 
			));
	}
	/**
	 * 将Task的循环属性(TaskCycle)转换到TaskDto中
	 * @param task
	 * @param dto
	 */
	private void cycleTask2dto(Task task , TaskDTO dto) {
		try {
			if (task == null ) { return;}//Task不能为空
			TaskCycle taskCycle = task.getTaskCycle();
			if ( taskCycle != null 
					&& ToolsConstant.TASK_TYPE_CYCLE_WEEK.equals( taskCycle.getType() )) {
				dto.setTaskCycle( taskCycle.getType() );
				dto.setCycleWeekEnd( taskCycle.getCycleType() );
				dto.setCycleCount( taskCycle.getCycleCount() );
				dto.setWeekWeeks( ToolsConstant.weeksIndex(taskCycle.getDateIndexVerify()) );
				
				dto.setStartDate( taskCycle.getStartDate() );
				dto.setEndDate( taskCycle.getEndDate() );
			}else{//普通任务
				dto.setTaskCycle(ToolsConstant.TASK_TYPE_NORMAL);
			}
		} catch (Exception e) {
			LOGGER.error(e);
		}
	}
	private void entity2dto(Task task, ScheduleJsonDTO dto) {
		dto.setTaskId(task.getTaskId());
		dto.setTitle( task.getTitle() );
		if (task.getOwner() != null) {
			dto.setTitle("[" + task.getOwner().getFullName() + "]" + task.getTitle());
		}
		dto.setStart(task.getStartTime());
		dto.setEnd(task.getEndTime());
		dto.setAllDay(task.getAllDay());
		if (task.getOwner() != null) {
			dto.setOwner(task.getOwner().getFullName());
			dto.setOwnerLoginName(task.getOwner().getLoginName());
		}
		if(task.getType()!=null){
			dto.setTaskType(task.getType().getDno());
		}
		dto.setIntroduction(task.getIntroduction());
		dto.setLocation(task.getLocation());
		if (task.getTaskCreator() != null) {
			dto.setCreator(task.getTaskCreator().getFullName());
			dto.setTaskCreator(task.getTaskCreator().getLoginName());
		}
		
		dto.setRealStartTime(task.getRealStartTime());
		dto.setRealEndTime(task.getRealEndTime());
		dto.setRealFree(task.getRealFree());
		dto.setTreatmentResults(task.getTreatmentResults());
		dto.setTaskCycle( task.taskCycleValue() );

		dto.setTaskStatus(task.getTaskStatus());
		CostDTO costDTO = findTaskCostWith( task.getTaskId() , task.getStartTime() , task.getEndTime(),dto.getTaskCycle() );
		if (costDTO != null && costDTO.checkProgressId()) {
			dto.setTaskStatus( costDTO.getStatus() );
		}else{
			dto.setTaskStatus( 0L );
		}
		if (dto.getTaskStatus() == 1) {// 进行中
			dto.setClassName("processing_fc-event-skin");
		} else if (dto.getTaskStatus() == 2) {// 已完成
			dto.setClassName("complete_fc-event-skin");
		} else {// 新建
			dto.setClassName("new_fc-event-skin");
		}
	}

	/**
	 * 根据任务ID获取任务DTO
	 * 
	 * @param taskId
	 * @return TaskDTO
	 */
	@Transactional
	public TaskDTO findById(Long taskId) {
		TaskDTO taskDto = new TaskDTO();
		Task task = taskDao.findById(taskId);
		entity2dto(task, taskDto);
		taskProperties(task);
		
		return taskDto;
	}

	@Transactional
	public TaskDTO findPortalById(Long taskId) {
		TaskDTO taskDto = new TaskDTO();
		Task task = taskDao.findById(taskId);
		entity2dto(task, taskDto);
		return taskDto;
	}

	/**
	 * 任务通知
	 * @param noticeRuleNo
	 * @param task
	 * @param owner
	 * @param creator
	 * @param operator
	 */
	private void taskNotice(String noticeRuleNo, Task task, String owner, String creator,
			String operator) {
		NoticeInfoDTO noticeInfoDto = new NoticeInfoDTO();
		noticeInfoDto.setNoticeRuleNo(noticeRuleNo);
		noticeInfoDto.setOwner(userDAO.findUniqueBy("loginName", owner));
		noticeInfoDto.setRequester(userDAO.findUniqueBy("loginName", creator));
		TaskDTO dto = new TaskDTO();
		entity2dto(task, dto);
		noticeInfoDto.setVariables(dto);
		noticeRuleService.commonNotice(noticeInfoDto);
	}


	@Transactional
	public InputStream exportTask(TaskQueryDTO taskQueryDto) {
		StringWriter sw = new StringWriter();
		CSVWriter csvw = new CSVWriter(sw);

		List<String[]> data = new ArrayList<String[]>();
		LanguageContent lc = LanguageContent.getInstance();

		data.add(new String[] { lc.getContent("label.user.cost.fullname"),
				lc.getContent("notice.currentActionName"),
				lc.getContent("label.request.taskDescription"),
				lc.getContent("title.task.taskStatus"),
				lc.getContent("label.dc.taskType"),
				lc.getContent("lable.scheduledStartTime"),
				lc.getContent("label.request.planComplete"),
				lc.getContent("lable.actualStartTime"),
				lc.getContent("label.request.completeTime"),
				lc.getContent("label.user.cost.ftime"),
				lc.getContent("label.user.cost.truefalse") });
		if ( taskQueryDto != null && 
				(taskQueryDto.getStartTime() == null || taskQueryDto.getEndTime() == null) ) {
			taskQueryDto.setStartTime( TimeUtils.getMonthFirstDay( null ));
			taskQueryDto.setEndTime( TimeUtils.getMonthLastDay( null ));
		}
		List<Task> taskList = taskDao.findMyAllTask(taskQueryDto);
		if (taskList != null) {
			List<Task> taskResult = TaskCycleUtil.taskCycleResolve(taskList, taskQueryDto );
			Collections.sort(taskResult);//排序
			for (Task item : taskResult) {
				if (item != null ) {
					String taskCycle = item.taskCycleValue();
					CostDTO costDTO = findTaskCostWith( item.getTaskId() , item.getStartTime(), item.getEndTime(),taskCycle );
					item = item.taskCycleInfo(costDTO);
					if (item.getTaskStatus().longValue() != -1L) {
						String taskStatus = String.valueOf(item.getTaskStatus())
								.replace("0", lc.getContent("title.newCreate"))
								.replace("1", lc.getContent("title.processing"))
								.replace("2", lc.getContent("titie.complete"));
						String realStartTime = "", realEndTime = "", realFree = "", real = "",type = "",fullName = "";
						if (item.getRealStartTime() != null) {
							realStartTime = TimeUtils.format(item.getRealStartTime(), TimeUtils.DATETIME_PATTERN);
						}
						if (item.getRealEndTime() != null) {
							realEndTime = TimeUtils.format(item.getRealEndTime(), TimeUtils.DATETIME_PATTERN);
						}
						if (item.getRealFree() != null) {
							double day = Math.floor(item.getRealFree() * 1 / 1440);
							double hour = Math.floor(item.getRealFree() * 1 % 1440 / 60);
							double Minute = Math.floor(item.getRealFree() * 1 % 1440 % 60);
							realFree = day + lc.getContent("label.sla.day")
									+ hour + lc.getContent("label.sla.hour")
									+ Minute + lc.getContent("label.sla.minute");
						}
						//是否按时完成
						if (String.valueOf(item.getTaskStatus()).equals("2")
								&& item.getRealEndTime() != null && item.getEndTime() != null) {
							if (item.getRealEndTime().getTime() > item.getEndTime().getTime()) {
								real = lc.getContent("label.dynamicReports.no");
							} else {
								real = lc.getContent("label.dynamicReports.yes");
							}
						}
						if (item.getOwner() != null) {
							fullName = item.getOwner().getFullName();
						}
						if (item.getType() != null) {
							type = item.getType().getDname();
						}
						data.add(new String[] { fullName, item.getTitle(),
								item.getIntroduction(), taskStatus, type,
								TimeUtils.format(item.getStartTime(), TimeUtils.DATETIME_PATTERN),
								TimeUtils.format(item.getEndTime(), TimeUtils.DATETIME_PATTERN),
								realStartTime, realEndTime, realFree, real });
					}
				}
			}
		}
		csvw.writeAll(data);
		byte[] bs = null;
		try {
			bs = sw.getBuffer().toString().getBytes("GBK");
		} catch (UnsupportedEncodingException e1) {
			LOGGER.error(EXPORTTASK_ERROR_INFO1, e1);
		}
		ByteArrayInputStream stream = null;
		if(bs!=null){
			stream = new ByteArrayInputStream(bs);
		}
		try {
			if (csvw != null) {
				csvw.flush();
				csvw.close();
			}
			if (sw != null) {
				sw.flush();
				sw.close();
			}
		} catch (IOException e) {
			LOGGER.error(e);
		}
		return stream;
	}

	/**
	 * 备注信息添加
	 */
	public void remarkTaskDetail(TaskDTO dto) {
		// 保存历史记录
		String logDetail = "Task Remark";
		if (StringUtils.hasText(dto.getTreatmentResults())) {
			logDetail += ( "："+dto.getTreatmentResults() );
		}
		saveHistoryRecord(dto,logDetail );
	}

	public boolean findTaskByIds(Long[] ids) {
		boolean bl = true;
		String operator = appctx.getCurrentLoginName();
		for (int i = 0; i < ids.length; i++) {
			Task task = taskDao.findById(ids[i]);
			if (!operator.equals(task.getCreator())) {
				bl = false;
			}
		}
		return bl;
	}

	@Transactional
	public TaskDTO taskRealTimeDefaultValue(Long taskId) {
		Date dt = new Date();
		TaskDTO taskDto = new TaskDTO();
		Task task = taskDao.findById(taskId);
		entity2dto(task, taskDto);
		if (task.getRealStartTime() == null) {
			taskDto.setRealStartTime(dt);
		}
		Long start = taskDto.getRealStartTime().getTime();
		Long end = dt.getTime();
		double real = (end - start) / 1000;
		real = real / 60;
		taskDto.setRealEndTime(dt);
		taskDto.setRealFree(real);
		return taskDto;
	}
	/**
	 * 
	 */
	public TaskDTO taskRealTimeDefaultValue(TaskDTO taskDTO) {
		Date dt = new Date();
		TaskDTO dto = findTaskCost(taskDTO);
		if (dto.getRealStartTime() == null) {
			dto.setRealStartTime(dt);
		}
		Long start = dto.getRealStartTime().getTime();
		Long end = dt.getTime();
		double real = (end - start) / 1000;
		real = real / 60;
		dto.setRealEndTime(dt);
		dto.setRealFree(real);
		return dto;
	}
	/**
	 * 查询指定时间段的所有排班任务的负责的用户名
	 * @param taskDto.startTime 不能为null，且必须
	 * @param taskDto.endTime 不能为null，且必须
	 * @return 如果开始时间与结束时间超过当前时间，那么查询的参数将是当前到今天晚上12点整
	 */
	public List<String> attendanceTaskByTimeRange(TaskDTO taskDto) {
		List<String> users = new ArrayList<String>();
		if (taskDto != null) {
			taskDto.setDno("task_workforce");
			Calendar calendar = Calendar.getInstance();
			if ( taskDto.getEndTime().before( calendar.getTime() )) {
				taskDto.setStartTime(calendar.getTime());
				taskDto.setEndTime( TimeUtils.getNowAllDay() );
			}else if ( taskDto.getStartTime().before( calendar.getTime() ) ){
				taskDto.setStartTime( calendar.getTime() );
			}
			List<Task> tasks = taskDao.findTimeRangeTask(taskDto);
			if (tasks != null) {
				TaskQueryDTO dto = new TaskQueryDTO( taskDto.getStartTime(),taskDto.getEndTime() );
				tasks = TaskCycleUtil.taskCycleResolve(tasks, dto);
				for (Task task : tasks) {
					if (task != null && task.getTaskStatus().longValue() != -1L
							&& task.getOwner() != null
							&& taskDto.getStartTime().getTime() < task.getEndTime().getTime()
							&& taskDto.getEndTime().getTime() > task.getStartTime().getTime()
							) {
						users.add( task.getOwner().getLoginName() );
					}
				}
			}
		}
		return users;
	}

	public TaskViewDTO findWorkForceShowData(TaskQueryDTO dto, String sidx,	String sord) {
		
		List<TaskShowDataDTO> data=new ArrayList<TaskShowDataDTO>();
		//获取排班任务
		getWorkForce(dto, data);
		
		TaskViewDTO viewDTO=new TaskViewDTO();
		viewDTO.setMinimumTime(TimeUtils.format(dto.getStartTime(), TimeUtils.DATE_PATTERN));
		viewDTO.setMaximumTime(TimeUtils.format(dto.getEndTime(), TimeUtils.DATE_PATTERN));
		viewDTO.setTaskShowDataDTO(data);
		return viewDTO;
	}
	
	private void getWorkForce(TaskQueryDTO qdto,List<TaskShowDataDTO> data){
		qdto.setSidx("owner");
		qdto.setSord("desc");
		List<Task> taskList = taskDao.findMyAllTask(qdto);
		if(taskList!=null&&taskList.size()>0){
			taskList = TaskCycleUtil.taskCycleResolve(taskList, qdto);
			for (Task task : taskList) {
				ScheduleJsonDTO dto=new ScheduleJsonDTO();
				entity2dto(task, dto);

				dto.setTaskType("workForce");
				dto.setTitle(task.getTitle());
				if (dto.getTaskStatus().longValue() != -1L) {
					TaskShowDataDTO dataDTO=new TaskShowDataDTO();
					User user = userDAO.findUniqueBy("loginName", task.getOwner().getLoginName());
					if (user != null) {
						dataDTO.setUserId(user.getUserId());
						dataDTO.setLoginName(user.getLoginName());
						dataDTO.setTechnician(user.getFullName());
					}
					dataDTO.setType("workForce");
					setTaskShowData(data, dataDTO, dto);
				}
			}
		}
	}
	private void setTaskShowData(List<TaskShowDataDTO> dataList,TaskShowDataDTO dataDTO,ScheduleJsonDTO dto){
		if(dataList!=null && dataList.size()>0){
			// 当前技术员是否已经存在于数据集合中，如果没有则直接添加，有的话去判断是否存在日期冲突
			if(isExistTechnician(dataDTO.getLoginName(), dataList)){
				dateConflict(dataList, dataDTO, dto);
		    }else{
		    	List<ScheduleJsonDTO> scheduleJsonDTOs=new ArrayList<ScheduleJsonDTO>();
				scheduleJsonDTOs.add(dto);
				dataDTO.setData(scheduleJsonDTOs);
				dataList.add(dataDTO);
		    }
	    }
		if(dataList!=null&&dataList.size()==0){
			List<ScheduleJsonDTO> scheduleJsonDTOs=new ArrayList<ScheduleJsonDTO>();
			scheduleJsonDTOs.add(dto);
			dataDTO.setData(scheduleJsonDTOs);
			dataList.add(dataDTO);
		}
		
	}
	
	/**
	 * 日期冲突的处理
	 * @param data
	 * @param showDataDTO
	 * @param scheduleJsonDTO
	 */
	private void dateConflict(List<TaskShowDataDTO> data, TaskShowDataDTO showDataDTO, ScheduleJsonDTO scheduleJsonDTO) {
	//是否加入已有的集合中
		boolean isload = false;
		for (TaskShowDataDTO dto : data) {
			boolean result = false;
			if(dto.getLoginName()!=null&& dto.getLoginName().equals(showDataDTO.getLoginName())){
				List<ScheduleJsonDTO> dtos=dto.getData();
				for (ScheduleJsonDTO jsonDTO : dtos) {
					if(beForSpecifiedTime(scheduleJsonDTO.getStart(),scheduleJsonDTO.getEnd(),jsonDTO.getStart(), jsonDTO.getEnd())){
						result=true;
						break;
					}
				}
				if(!result){
					isload=true;
					dtos.add(scheduleJsonDTO);
					dto.setData(dtos);
					break;
				}
			}
		}
		if(!isload){
			List<ScheduleJsonDTO> sjd=new ArrayList<ScheduleJsonDTO>();
			sjd.add(scheduleJsonDTO);
			showDataDTO.setData(sjd);
			data.add(showDataDTO);
		}
	}
	
	/**
	 * 判断这个List中是否已存在指定的技术员
	 * 
	 * @param technician
	 * @param data
	 * @return boolean
	 */
	private boolean isExistTechnician(String technician, List<TaskShowDataDTO> dataList) {
		boolean result = false;
		for (TaskShowDataDTO dto : dataList) {
			if (technician != null && technician.equals(dto.getLoginName())) {
				result = true;
				break;
			}
		}
		return result;
	}
	
	/**
	 * 判断是否在指定时间范围内
	 * @param startTime1
	 * @param endTime1
	 * @param startTime
	 * @param endTime
	 * @return
	 */
	public  boolean beForSpecifiedTime(Date startTime1, Date endTime1, Date startTime,Date endTime) {
		startTime1 = TimeUtils.dateFormat(startTime1,TimeUtils.DATE_PATTERN);
		endTime1 = TimeUtils.dateFormat(endTime1,TimeUtils.DATE_PATTERN);
		startTime = TimeUtils.dateFormat(startTime,TimeUtils.DATE_PATTERN);
		endTime = TimeUtils.dateFormat(endTime,TimeUtils.DATE_PATTERN);
		// 如果开始时间及结束时间都在指定的时间范围内，那么说明在时间有有冲突
		if ((startTime1.getTime() >= startTime.getTime() && startTime1.getTime() <= endTime.getTime())
			|| (endTime1.getTime() >= startTime.getTime() && endTime1.getTime() <= endTime.getTime())
			|| (startTime.getTime() >= startTime1.getTime() && startTime.getTime() <= endTime1.getTime())
			|| (endTime.getTime() >= startTime1.getTime() && endTime.getTime() <= endTime1.getTime())){
			return true;
		}
		return false;
	}
	
	
	//--------------------
	public CostDTO findTaskCostWith(Long taskId, Date startTime,Date endTime,String taskCycle) {
		TaskDTO taskDTO = new TaskDTO();
		taskDTO.setTaskId( taskId );
		taskDTO.setStartTime( startTime );
		taskDTO.setEndTime( endTime );
		taskDTO.setTaskCycle( taskCycle );
		return costService.findScheduleCost( taskDTO );
	}
	
	@Transactional
	public CostDTO saveTaskCostWith(TaskDTO dto) {
		CostDTO costDTO = costService.findScheduleCost(dto);
		if( costDTO != null && costDTO.checkProgressId() ){
			costDTO.setEndTime( new Date() );
			costDTO.setOpertionTime( new Date() );
			/*if (dto.getTaskCycle() == null 
					|| dto.getTaskCycle().equals(ToolsConstant.TASK_TYPE_NORMAL)) {
				//costDTO.setEndTime( dto.getEndTime() );
			}*/
			if ( ToolsConstant.TASK_TYPE_CYCLE_WEEK.equals(dto.getTaskCycle())) {
				Date endTime = TimeUtils.getMinDate(TimeUtils.getAllDayLast(dto.getEndTime()),new Date()).getTime();
				costDTO.setEndTime( endTime );
			}
			Long endMin = 0L;
			Long setartMin = 0L;
			if (dto.getRealStartTime() != null && dto.getRealEndTime() != null) {
				costDTO.setStartTime( dto.getRealStartTime() );
				costDTO.setEndTime( dto.getRealEndTime() );
				setartMin = dto.getRealStartTime().getTime() / TimeUtils.MINU_MILLISECONDS;
				endMin = dto.getRealEndTime().getTime() / TimeUtils.MINU_MILLISECONDS;
			}else{
				setartMin = costDTO.getStartTime().getTime() / TimeUtils.MINU_MILLISECONDS;
				endMin = costDTO.getEndTime().getTime() / TimeUtils.MINU_MILLISECONDS;
			}
			costDTO.setDescription(dto.getTreatmentResults());
			costDTO.setActualTime(endMin - setartMin);
			costDTO.setStatus(2L);
			costService.editCost(costDTO);
		}else{
			costDTO = new CostDTO();
			costDTO.setScheduleTaskTime(dto.getStartTime());
			// 保存进展及成本
			User user = userDAO.findUniqueBy("loginName",dto.getOwnerLoginName());
			if (user != null){
				costDTO.setUserId(user.getUserId());
			}
			costDTO.setScheduleTaskId( dto.getTaskId() );
			costDTO.setEventType( ToolsConstant.TYPE_OTHER_IS_TASK );

			costDTO.setStartTime( new Date() );
			if (dto.getEndTime() != null) {
				Long setartMin = costDTO.getStartTime().getTime() / TimeUtils.MINU_MILLISECONDS;
				Long endMin = dto.getEndTime().getTime() / TimeUtils.MINU_MILLISECONDS;
				costDTO.setStartToEedTime( endMin - setartMin);
			}
			costDTO.setStatus(1L);
			costDTO.setStartTime(costDTO.getStartTime());
			costService.saveCost(costDTO);
		}
		return costDTO;
	}

	public TaskDTO findTaskCostWith(TaskDTO taskDto) {
		taskDto.setCostDTO( costService.findScheduleCost( taskDto ) );
		return taskDto;
	}
	
	public Task taskProperties(Task task) {
		try {
			CostDTO costDTO = findTaskCostWith(task.getTaskId(), task.getStartTime(), task.getEndTime() , task.taskCycleValue());
			if (costDTO != null) {
				task.setTaskStatus( costDTO.getStatus() );
			}
		} catch (Exception e) {
			LOGGER.error(e);
		}
		return task;
	}
	
	//--------------------
	public TaskDTO findTaskCost(TaskDTO taskDto) {
		if ( !TaskDTO.validTask(taskDto) ) {
			return taskDto;
		}
		Task task = taskDao.findById( taskDto.getTaskId() );
		taskDto.setTaskCycle( task.taskCycleValue() );//设置循环类型
		CostDTO costDTO = costService.findScheduleCost( taskDto );
		task = TaskCycleUtil.taskCycleResolve(task, taskDto.getStartTime() , taskDto.getEndTime() );
		TaskDTO dto = new TaskDTO();
		entity2dto(task, dto);
		dto.setCostDTO( costDTO );
		return dto;
	}
	/**
	 * 开始处理
	 */
	@Transactional
	public void editTaskDetail(TaskDTO taskDto) {
		TaskDTO dto = findTaskCost(taskDto);
		if (dto != null && dto.getTaskId() != null) {
			Task task = taskDao.findById(dto.getTaskId());
			dto.setTaskStatus( 1L );
			if( task.taskNotCycle() ){
				task.setTaskStatus(dto.getTaskStatus());
				taskDao.merge(task);
			}
			saveTaskCost(dto);
			// 保存历史记录
			saveHistoryRecord(taskDto, "Task Processing");
			taskNotice("taskProcessNoticeOwner", task, task.getOwnerLoginName(), task.getTaskCreatorLoginName(), dto.getOperator());
		}
	}
	@Transactional
	public void closedTaskDetail(TaskDTO dto) {
		TaskDTO taskDto = findTaskCost(dto);
		
		Task tk = taskDao.findById(dto.getTaskId());
		dto.setTaskStatus( 2L );
		if( tk.taskNotCycle() ){
			tk.setTaskStatus(dto.getTaskStatus());
			taskDao.merge(tk);
		}
		
		CostDTO costDTO = taskDto.getCostDTO();
		if ( costDTO != null && costDTO.checkProgressId() ) {
			
			costDTO.setOpertionTime( new Date() );
			costDTO.setStartTime( dto.getRealStartTime() );
			costDTO.setEndTime( dto.getRealEndTime() );
			if (costDTO.getStartTime() == null) {
				costDTO.setStartTime( dto.getStartTime() );
			}
			if ( costDTO.getEndTime() == null ) {
				costDTO.setEndTime( new Date() );
			}
			if ( dto.getRealFree() != null) {
				costDTO.setActualTime( dto.getRealFree().longValue() );
			}else{
				Long endMin = costDTO.getEndTime().getTime() / TimeUtils.MINU_MILLISECONDS;
				Long startMin = costDTO.getStartTime().getTime() / TimeUtils.MINU_MILLISECONDS;
				costDTO.setActualTime(endMin - startMin);
				if ( endMin < startMin ) {
					costDTO.setStartToEedTime( 0L );
				}
			}
			
			costDTO.setDescription(dto.getTreatmentResults());
			costDTO.setStatus(2L);
			
			costService.editCost(costDTO);
			
			Task task = taskDao.findById(dto.getTaskId());
			saveHistoryRecord(dto, "Task Closed");
			taskNotice("taskClosedNoticeOwner", task, task.getOwnerLoginName(), task.getTaskCreatorLoginName(), dto.getOperator());
		}
	}
	@Transactional
	public CostDTO saveTaskCost(TaskDTO dto) {
		CostDTO costDTO = new CostDTO();
		costDTO.setScheduleTaskTime(dto.getStartTime());
		// 保存进展及成本
		User user = userDAO.findUniqueBy("loginName",dto.getOwnerLoginName());
		if (user != null){
			costDTO.setUserId(user.getUserId());
		}
		costDTO.setScheduleTaskId( dto.getTaskId() );
		costDTO.setEventType( ToolsConstant.TYPE_OTHER_IS_TASK );

		costDTO.setStartTime( new Date() );
		if (dto.getEndTime() != null) {
			Long startMin = costDTO.getStartTime().getTime() / TimeUtils.MINU_MILLISECONDS;
			Long endMin = dto.getEndTime().getTime() / TimeUtils.MINU_MILLISECONDS;
			costDTO.setStartToEedTime( endMin - startMin);
			if ( endMin < startMin ) {
				costDTO.setStartToEedTime( 0L );
			}
		}
		if (dto.getTaskStatus() != null) {
			costDTO.setStatus( dto.getTaskStatus() );
		}else{
			costDTO.setStatus(1L);
		}
		costService.saveCost(costDTO);
		return costDTO;
	}

	@Override
	public void setTaskDao(ITaskDAO taskDAO) {
		this.taskDao = taskDAO;
		
	}

}